package day28.homework;

/*
 * 1. 定义子线程1，线程处理函数中输出 1-50，每隔5ms输出一次 
 * 2. 定义子线程2，线程处理函数中输出 A-Z，每隔10ms输出一次 
 * 3. 要求，当线程1输出30之后，线程2插队进来优先输出，全部输出后，线程1再输出31-50。
 */

public class hw5 {
    // 使用volatile关键字确保线程间变量的可见性，当一个线程修改了这个变量的值，
    // 其他线程能够立即看到这个修改，避免因线程缓存导致的数据不一致问题
    private static volatile boolean shouldInterupt = false;
    // 用于标识插队线程是否执行完成的标志位，同样使用volatile保证可见性
    private static volatile boolean interuptFinished = false;

    public static void main(String[] args) {
        // 创建线程1：负责输出数字1-50，模拟主线程任务
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                // 循环输出1到50的数字
                for (int i = 1; i <= 50; i++) {
                    // 当输出到30时，设置插队标志，让线程2优先执行
                    if (i == 30) {
                        System.out.print(i + " ");
                        // 设置插队标志，通知线程2可以开始执行
                        shouldInterupt = true;
                        
                        // 等待插队线程执行完毕，通过轮询检查interuptFinished标志
                        while (!interuptFinished) {
                            try {
                                // 短暂休眠，避免过度占用CPU资源
                                Thread.sleep(1);
                            } catch (InterruptedException e) {
                                // 处理线程中断异常
                                e.printStackTrace();
                            }
                        }
                        // 跳过后续代码，继续下一次循环
                        continue;
                    }
                    // 输出当前数字并添加空格分隔
                    System.out.print(i + " ");
                    try {
                        // 每隔5ms输出一次，控制输出速度，让执行过程更清晰可见
                        Thread.sleep(5); // 每隔5ms输出一次
                    } catch (InterruptedException e) {
                        // 处理线程中断异常
                        e.printStackTrace();
                    }
                }
            }
        });

        // 创建线程2：负责输出A-Z字母，模拟插队执行的任务
        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                // 等待线程1输出到30，通过轮询检查shouldInterupt标志
                while (!shouldInterupt) {
                    try {
                        // 短暂休眠，避免过度占用CPU资源
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                        // 处理线程中断异常
                        e.printStackTrace();
                    }
                }

                // 在新行开始输出字母，使输出结果更清晰
                System.out.println();

                // 输出A-Z字母序列
                for (char c = 'A'; c <= 'Z'; c++) {
                    // 输出当前字母并添加空格分隔
                    System.out.print(c + " ");
                    try {
                        // 每隔10ms输出一次，控制输出速度
                        Thread.sleep(10); // 每隔10ms输出一次
                    } catch (InterruptedException e) {
                        // 处理线程中断异常
                        e.printStackTrace();
                    }
                }
                // 输出完成后换行，使输出结果更清晰
                System.out.println();
                // 标记插队完成，通知线程1可以继续执行
                interuptFinished = true;
            }
        });

        // 启动两个线程，开始并发执行
        thread1.start();
        thread2.start();

        // 等待两个线程执行完毕，确保主线程等待所有子线程完成
        try {
            // 等待thread1执行完毕
            thread1.join();
            // 等待thread2执行完毕
            thread2.join();
        } catch (InterruptedException e) {
            // 处理线程中断异常
            e.printStackTrace();
        }

        // 所有线程执行完毕后输出提示信息
        System.out.println("\n所有线程执行完毕");
    }
}